#pragma once

/*
    Configuration
*/
#ifndef CPPHTTPLIB_REDIRECT_MAX_COUNT
#define CPPHTTPLIB_REDIRECT_MAX_COUNT 20
#endif

#ifndef CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND
#define CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND 5
#endif

#ifndef CPPHTTPLIB_KEEPALIVE_MAX_COUNT
#define CPPHTTPLIB_KEEPALIVE_MAX_COUNT 5
#endif

#ifndef CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND
#define CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND 300
#endif

#ifndef CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND
#define CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND 0
#endif

#ifndef CPPHTTPLIB_READ_TIMEOUT_SECOND
#define CPPHTTPLIB_READ_TIMEOUT_SECOND 5
#endif

#ifndef CPPHTTPLIB_READ_TIMEOUT_USECOND
#define CPPHTTPLIB_READ_TIMEOUT_USECOND 0
#endif

#ifndef CPPHTTPLIB_WRITE_TIMEOUT_SECOND
#define CPPHTTPLIB_WRITE_TIMEOUT_SECOND 5
#endif

#ifndef CPPHTTPLIB_WRITE_TIMEOUT_USECOND
#define CPPHTTPLIB_WRITE_TIMEOUT_USECOND 0
#endif

#ifndef CPPHTTPLIB_IDLE_INTERVAL_SECOND
#define CPPHTTPLIB_IDLE_INTERVAL_SECOND 0
#endif

#ifndef CPPHTTPLIB_IDLE_INTERVAL_USECOND
#ifdef _WIN32
#define CPPHTTPLIB_IDLE_INTERVAL_USECOND 10000
#else
#define CPPHTTPLIB_IDLE_INTERVAL_USECOND 0
#endif
#endif

#ifndef CPPHTTPLIB_REQUEST_URI_MAX_LENGTH
#define CPPHTTPLIB_REQUEST_URI_MAX_LENGTH 8192
#endif

#ifndef CPPHTTPLIB_HEADER_MAX_LENGTH
#define CPPHTTPLIB_HEADER_MAX_LENGTH 8192
#endif

#ifndef CPPHTTPLIB_REDIRECT_MAX_COUNT
#define CPPHTTPLIB_REDIRECT_MAX_COUNT 20
#endif

#ifndef CPPHTTPLIB_MULTIPART_FORM_DATA_FILE_MAX_COUNT
#define CPPHTTPLIB_MULTIPART_FORM_DATA_FILE_MAX_COUNT 1024
#endif

#ifndef CPPHTTPLIB_PAYLOAD_MAX_LENGTH
#define CPPHTTPLIB_PAYLOAD_MAX_LENGTH ((std::numeric_limits<size_t>::max)())
#endif

#ifndef CPPHTTPLIB_FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH
#define CPPHTTPLIB_FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH 8192
#endif

#ifndef CPPHTTPLIB_TCP_NODELAY
#define CPPHTTPLIB_TCP_NODELAY false
#endif

#ifndef CPPHTTPLIB_RECV_BUFSIZ
#define CPPHTTPLIB_RECV_BUFSIZ size_t(4096u)
#endif

#ifndef CPPHTTPLIB_COMPRESSION_BUFSIZ
#define CPPHTTPLIB_COMPRESSION_BUFSIZ size_t(16384u)
#endif

#ifndef CPPHTTPLIB_THREAD_POOL_COUNT
#define CPPHTTPLIB_THREAD_POOL_COUNT                              \
    ((std::max)(8u, std::thread::hardware_concurrency() > 0       \
                        ? std::thread::hardware_concurrency() - 1 \
                        : 0))
#endif

#ifndef CPPHTTPLIB_RECV_FLAGS
#define CPPHTTPLIB_RECV_FLAGS 0
#endif

#ifndef CPPHTTPLIB_SEND_FLAGS
#define CPPHTTPLIB_SEND_FLAGS 0
#endif

#ifndef CPPHTTPLIB_LISTEN_BACKLOG
#define CPPHTTPLIB_LISTEN_BACKLOG 5
#endif

/*
    include
*/

#ifdef _WIN32
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif //_CRT_SECURE_NO_WARNINGS

#ifndef _CRT_NONSTDC_NO_DEPRECATE
#define _CRT_NONSTDC_NO_DEPRECATE
#endif //_CRT_NONSTDC_NO_DEPRECATE

#if defined(_MSC_VER)
#if _MSC_VER < 1900
#error Sorry, Visual Studio versions prior to 2015 are not supported
#endif

#pragma comment(lib, "ws2_32.lib")

#ifdef _WIN64
using ssize_t = __int64;
#else
using ssize_t = long;
#endif
#endif // _MSC_VER

#ifndef S_ISREG
#define S_ISREG(m) (((m) & S_IFREG) == S_IFREG)
#endif // S_ISREG

#ifndef S_ISDIR
#define S_ISDIR(m) (((m) & S_IFDIR) == S_IFDIR)
#endif // S_ISDIR

#ifndef NOMINMAX
#define NOMINMAX
#endif // NOMINMAX

#include <io.h>
#include <winsock2.h>
#include <ws2tcpip.h>

#ifndef WSA_FLAG_NO_HANDLE_INHERIT
#define WSA_FLAG_NO_HANDLE_INHERIT 0x80
#endif

using socket_t = SOCKET;
#ifdef CPPHTTPLIB_USE_POLL
#define poll(fds, nfds, timeout) WSAPoll(fds, nfds, timeout)
#endif

#else // not _WIN32

#include <arpa/inet.h>
#if !defined(_AIX) && !defined(__MVS__)
#include <ifaddrs.h>
#endif
#ifdef __MVS__
#include <strings.h>
#ifndef NI_MAXHOST
#define NI_MAXHOST 1025
#endif
#endif
#include <net/if.h>
#include <netdb.h>
#include <netinet/in.h>
#ifdef __linux__
#include <resolv.h>
#endif
#include <netinet/tcp.h>
#ifdef CPPHTTPLIB_USE_POLL
#include <poll.h>
#endif
#include <csignal>
#include <pthread.h>
#include <sys/mman.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/stat.h>


using socket_t = int;
#ifndef INVALID_SOCKET
#define INVALID_SOCKET (-1)
#endif
#endif //_WIN32

#include <functional>
#include <map>
#include <unordered_map>
#include <vector>
#include <regex>
#include <algorithm>
#include <iostream>
#include <chrono>
#include <thread>
#include <mutex>
#include <list>
#include <condition_variable>
#include <cassert>
#include <atomic>
#include <fstream>
#include <iomanip>

namespace httplib
{

    namespace detail
    {

        //c++11的make_unique
        template <class T, class... Args>
        typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
        make_unique(Args &&...args)
        {
            return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
        }

        template <class T>
        typename std::enable_if<std::is_array<T>::value, std::unique_ptr<T>>::type
        make_unique(std::size_t n)
        {
            typedef typename std::remove_extent<T>::type RT;
            return std::unique_ptr<T>(new RT[n]);
        }

        // headers排序
        struct ci
        {
            bool operator()(const std::string &s1, const std::string &s2) const
            {
                return std::lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end(),
                                                    [](unsigned char c1, unsigned char c2)
                                                    {
                                                        // ::确保是全局作用域的tolower
                                                        return ::tolower(c1) < ::tolower(c2);
                                                    });
            }
        };
    } // namespace detail

    // HTTP状态码
    enum StatusCode
    {
        // Information responses
        Continue_100 = 100,
        SwitchingProtocol_101 = 101,
        Processing_102 = 102,
        EarlyHints_103 = 103,

        // Successful responses
        OK_200 = 200,
        Created_201 = 201,
        Accepted_202 = 202,
        NonAuthoritativeInformation_203 = 203,
        NoContent_204 = 204,
        ResetContent_205 = 205,
        PartialContent_206 = 206,
        MultiStatus_207 = 207,
        AlreadyReported_208 = 208,
        IMUsed_226 = 226,

        // Redirection messages
        MultipleChoices_300 = 300,
        MovedPermanently_301 = 301,
        Found_302 = 302,
        SeeOther_303 = 303,
        NotModified_304 = 304,
        UseProxy_305 = 305,
        unused_306 = 306,
        TemporaryRedirect_307 = 307,
        PermanentRedirect_308 = 308,

        // Client error responses
        BadRequest_400 = 400,
        Unauthorized_401 = 401,
        PaymentRequired_402 = 402,
        Forbidden_403 = 403,
        NotFound_404 = 404,
        MethodNotAllowed_405 = 405,
        NotAcceptable_406 = 406,
        ProxyAuthenticationRequired_407 = 407,
        RequestTimeout_408 = 408,
        Conflict_409 = 409,
        Gone_410 = 410,
        LengthRequired_411 = 411,
        PreconditionFailed_412 = 412,
        PayloadTooLarge_413 = 413,
        UriTooLong_414 = 414,
        UnsupportedMediaType_415 = 415,
        RangeNotSatisfiable_416 = 416,
        ExpectationFailed_417 = 417,
        ImATeapot_418 = 418,
        MisdirectedRequest_421 = 421,
        UnprocessableContent_422 = 422,
        Locked_423 = 423,
        FailedDependency_424 = 424,
        TooEarly_425 = 425,
        UpgradeRequired_426 = 426,
        PreconditionRequired_428 = 428,
        TooManyRequests_429 = 429,
        RequestHeaderFieldsTooLarge_431 = 431,
        UnavailableForLegalReasons_451 = 451,

        // Server error responses
        InternalServerError_500 = 500,
        NotImplemented_501 = 501,
        BadGateway_502 = 502,
        ServiceUnavailable_503 = 503,
        GatewayTimeout_504 = 504,
        HttpVersionNotSupported_505 = 505,
        VariantAlsoNegotiates_506 = 506,
        InsufficientStorage_507 = 507,
        LoopDetected_508 = 508,
        NotExtended_510 = 510,
        NetworkAuthenticationRequired_511 = 511,
    };

    using Headers = std::multimap<std::string, std::string, detail::ci>;
    using Params = std::multimap<std::string, std::string>;
    using Match = std::smatch;
    using Progress = std::function<bool(uint64_t current, uint64_t total)>;

    struct Response;
    using ResponseHandler = std::function<bool(const Response &)>;

    struct MultipartFormData
    {
        std::string name;         // 表单字段名称
        std::string content;      // 文件的内容
        std::string filename;     // 文件名称
        std::string content_type; // 文件类型
    };
    using MultipartFormDataItems = std::vector<MultipartFormData>;

    using MultipartFormDataMap = std::multimap<std::string, MultipartFormData>;

    // 数据接收器
    class DataSink
    {
    public:
        // 构造函数，将os和sb_关联起来
        DataSink() : os(&sb_), sb_(*this) {}

        // 保证数据一致性
        DataSink(const DataSink &) = delete;
        DataSink &operator=(const DataSink &) = delete;
        DataSink(DataSink &&) = delete;
        DataSink &operator=(DataSink &&) = delete;

        // 回调函数
        std::function<bool(const char *data, size_t data_len)> write;  // 将数据写入数据接收器
        std::function<bool()> is_writable;                             // 检查数据接收器是否可写
        std::function<void()> done;                                    // 数据接收器写完后调用
        std::function<void(const Headers &trailer)> done_with_trailer; // 写完后调用并传递trailer作为参数

        std::ostream os;

    private:
        // 嵌套类
        class data_sink_streambuf : public std::streambuf
        {
        public:
            // 防止隐式创建，即只能通过new来创建
            explicit data_sink_streambuf(DataSink &sink) : sink_(sink) {}

        protected:
            std::streamsize xsputn(const char *s, std::streamsize n) override
            {
                sink_.write(s, static_cast<size_t>(n));
                return n;
            }

        private:
            DataSink &sink_;
        };

        data_sink_streambuf sb_;
    };

    using ContentProvider =
        std::function<bool(size_t offset, size_t length, DataSink &sink)>;

    using ContentProviderWithoutLength =
        std::function<bool(size_t offset, DataSink &sink)>;

    using ContentProviderResourceReleaser = std::function<void(bool success)>;

    struct MultipartFormDataProvider
    {
        std::string name;
        ContentProviderWithoutLength provider;
        std::string filename;
        std::string content_type;
    };

    using MultipartFormDataProviderItems = std::vector<MultipartFormDataProvider>;

    using ContentReceiverWithProgress =
        std::function<bool(const char *data, size_t data_length, uint64_t offset,
                           uint64_t total_length)>;

    using ContentReceiver =
        std::function<bool(const char *data, size_t data_length)>;

    using MultipartContentHeader =
        std::function<bool(const MultipartFormData &file)>;

    class ContentReader
    {
    public:
        using Reader = std::function<bool(ContentReceiver receiver)>;
        using MultipartReader = std::function<bool(MultipartContentHeader header,
                                                   ContentReceiver receiver)>;

        ContentReader(Reader reader, MultipartReader multipart_reader)
            : reader_(std::move(reader)),
              multipart_reader_(std::move(multipart_reader)) {}

        bool operator()(MultipartContentHeader header,
                        ContentReceiver receiver) const
        {
            return multipart_reader_(std::move(header), std::move(receiver));
        }

        bool operator()(ContentReceiver receiver) const
        {
            return reader_(std::move(receiver));
        }

        Reader reader_;
        MultipartReader multipart_reader_;
    };

    using Range = std::pair<ssize_t, ssize_t>; //{100,199}从第100到199字节
    using Ranges = std::vector<Range>;

    // 请求
    struct Request
    {
        std::string method; //"GET" "POST" "PUT"
        std::string path;   //   /path/to/resource
        Headers headers;    // 请求头
        std::string body;   // 请求体

        std::string remote_addr;
        int remote_port;
        std::string local_addr;
        int local_port;

        // for server
        std::string version;                                      // "HTTP/1.1"
        std::string target;                                       // http://localhost:8080/path/to/resource
        Params params;                                            // URL参数 ?name="nie"&age=11
        MultipartFormDataMap files;                               // 文件参数
        Ranges ranges;                                            // 断点续传、并行下载
        Match matches;                                            // 匹配路径 正则表达式
        std::unordered_map<std::string, std::string> path_params; // 路径参数/users/#{123}

        // for client
        ResponseHandler response_handler;             // 响应处理器
        ContentReceiverWithProgress content_receiver; // 内容接收器
        Progress progress;                            // 请求进度

        // 成员函数,const表示不修改任何成员变量
        bool has_header(const std::string &key) const;                                // 判断是否有某个请求头
        std::string get_header_value(const std::string &key, size_t id = 0) const;    // 获得请求头的值
        uint64_t get_header_value_u64(const std::string &key, size_t id = 0) const;   // content-length
        size_t get_header_value_count(const std::string &key) const;                  // 获得请求头值的数量
        void set_header(const std::string &key, const std::string &val);              // 设置请求头
        bool has_param(const std::string &key) const;                                 // 判断是否有某个URL参数
        std::string get_param_value(const std::string &key, size_t id = 0) const;     // 获取URL参数的值
        size_t get_param_value_count(const std::string &key) const;                   // 获取URL参数值的数量
        bool is_multipart_form_data() const;                                          // 判断是否有multipart表单数据
        bool has_file(const std::string &key) const;                                  // 判断是否有某个文件
        MultipartFormData get_file_value(const std::string &key) const;               // 获取文件值
        std::vector<MultipartFormData> get_file_values(const std::string &key) const; // 获取文件值的数组

        // 私有成员
        size_t redirect_count_ = CPPHTTPLIB_REDIRECT_MAX_COUNT; // 最多重定向次数
        size_t content_length_;                                 // 请求的内容长度
        ContentProvider content_provider_;                      // 内容提供器
        bool is_chunked_content_provider_ = false;              // 是否是否实现了分块传输编码的内容提供器
        size_t authorization_count_ = 0;                        // 认证次数
    };

    // 响应
    struct Response
    {
        std::string version;
        int status = -1;    // 200 400
        std::string reason; // OK NOT FOUND
        Headers headers;
        std::string body;
        std::string location; // Redirect location

        bool has_header(const std::string &key) const;
        std::string get_header_value(const std::string &key, size_t id = 0) const;
        uint64_t get_header_value_u64(const std::string &key, size_t id = 0) const;
        size_t get_header_value_count(const std::string &key) const;
        void set_header(const std::string &key, const std::string &val);

        void set_redirect(const std::string &url, int status = StatusCode::Found_302);
        void set_content(const char *s, size_t n, const std::string &content_type);
        void set_content(const std::string &s, const std::string &content_type);

        // 设置一个内容提供者来提供响应体。
        void set_content_provider(
            size_t length, const std::string &content_type, ContentProvider provider,
            ContentProviderResourceReleaser resource_releaser = nullptr);

        void set_content_provider(
            const std::string &content_type, ContentProviderWithoutLength provider,
            ContentProviderResourceReleaser resource_releaser = nullptr);

        void set_chunked_content_provider(
            const std::string &content_type, ContentProviderWithoutLength provider,
            ContentProviderResourceReleaser resource_releaser = nullptr);

        Response() = default;
        Response(const Response &) = default;
        Response &operator=(const Response &) = default;
        Response(Response &&) = default;
        Response &operator=(Response &&) = default;
        ~Response()
        {
            // 如果有释放则调用
            if (content_provider_resource_releaser_)
            {
                content_provider_resource_releaser_(content_provider_success_);
            }
        }

        // private members...
        size_t content_length_ = 0;                                          // 响应体的内容长度
        ContentProvider content_provider_;                                   // 内容提供者
        ContentProviderResourceReleaser content_provider_resource_releaser_; // 释放器，接收contentProvider是否操作成功
        bool is_chunked_content_provider_ = false;                           // 是否支持分块
        bool content_provider_success_ = false;                              // contentProvider的操作结果：未完成/失败/完成
    };

    // 处理数据读取与写入
    class Stream
    {
    public:
        virtual ~Stream() = default;

        virtual bool is_readable() const = 0;
        virtual bool is_writable() const = 0;

        virtual ssize_t read(char *ptr, size_t size) = 0;
        virtual ssize_t write(const char *ptr, size_t size) = 0;
        virtual void get_remote_ip_and_port(std::string &ip, int &port) const = 0;
        virtual void get_local_ip_and_port(std::string &ip, int &port) const = 0;
        virtual socket_t socket() const = 0; // 获取套接字句柄

        template <typename... Args>
        ssize_t write_format(const char *fmt, const Args &...args);
        ssize_t write(const char *ptr);
        ssize_t write(const std::string &s);
    };

    class TaskQueue
    {
    public:
        TaskQueue() = default;
        virtual ~TaskQueue() = default;

        virtual bool enqueue(std::function<void()> fn) = 0;
        virtual void shutdown() = 0;

        virtual void on_idle() {}
    };

    class ThreadPool : public TaskQueue
    {
    public:
        explicit ThreadPool(size_t n, size_t mqr = 0)
            : shutdown_(false), max_queued_requests_(mqr)
        {
            while (n)
            {
                threads_.emplace_back(worker(*this));
                n--;
            }
        }

        ThreadPool(const ThreadPool &) = delete;
        ~ThreadPool() override = default;

        bool enqueue(std::function<void()> fn) override
        {
            {
                std::unique_lock<std::mutex> lock(mutex_);
                if (max_queued_requests_ > 0 && jobs_.size() >= max_queued_requests_)
                {
                    return false;
                }
                jobs_.push_back(std::move(fn));
            }

            cond_.notify_one();
            return true;
        }

        void shutdown() override
        {
            // 终止所有工作线程
            {
                std::unique_lock<std::mutex> lock(mutex_);
                shutdown_ = true;
            }

            cond_.notify_all();

            // 等待所有线程
            for (auto &t : threads_)
            {
                t.join();
            }
        }

    private:
        struct worker
        {
            explicit worker(ThreadPool &pool) : pool_(pool) {}

            void operator()()
            {
                for (;;)
                {
                    std::function<void()> fn;
                    {
                        std::unique_lock<std::mutex> lock(pool_.mutex_);

                        pool_.cond_.wait(
                            lock, [&]
                            { return !pool_.jobs_.empty() || pool_.shutdown_; });

                        if (pool_.shutdown_ && pool_.jobs_.empty())
                        {
                            break;
                        }

                        fn = std::move(pool_.jobs_.front());
                        pool_.jobs_.pop_front();
                    }

                    assert(true == static_cast<bool>(fn));
                    fn();
                }
            }

            ThreadPool &pool_;
        };
        friend struct worker;

        std::vector<std::thread> threads_;
        std::list<std::function<void()>> jobs_;

        bool shutdown_;
        size_t max_queued_requests_ = 0;

        std::condition_variable cond_;
        std::mutex mutex_;
    };

    // 日志器
    using Logger = std::function<void(const Request &, const Response &)>;

    using SocketOptions = std::function<void(socket_t sock)>;

    using Progress = std::function<bool(uint64_t current, uint64_t total)>;

    namespace detail
    {

        class MatcherBase
        {
        public:
            virtual ~MatcherBase() = default;

            // Match request path and populate its matches and
            virtual bool match(Request &request) const = 0;
        };

        /**
         * Captures parameters in request path and stores them in Request::path_params
         *
         * Capture name is a substring of a pattern from : to /.
         * The rest of the pattern is matched agains the request path directly
         * Parameters are captured starting from the next character after
         * the end of the last matched static pattern fragment until the next /.
         *
         * Example pattern:
         * "/path/fragments/:capture/more/fragments/:second_capture"
         * Static fragments:
         * "/path/fragments/", "more/fragments/"
         *
         * Given the following request path:
         * "/path/fragments/:1/more/fragments/:2"
         * the resulting capture will be
         * {{"capture", "1"}, {"second_capture", "2"}}
         */
        class PathParamsMatcher : public MatcherBase
        {
        public:
            PathParamsMatcher(const std::string &pattern);

            bool match(Request &request) const override;

        private:
            static constexpr char marker = ':';
            // Treat segment separators as the end of path parameter capture
            // Does not need to handle query parameters as they are parsed before path
            // matching
            static constexpr char separator = '/';

            // Contains static path fragments to match against, excluding the '/' after
            // path params
            // Fragments are separated by path params
            std::vector<std::string> static_fragments_;
            // Stores the names of the path parameters to be used as keys in the
            // Request::path_params map
            std::vector<std::string> param_names_;
        };

        /**
         * Performs std::regex_match on request path
         * and stores the result in Request::matches
         *
         * Note that regex match is performed directly on the whole request.
         * This means that wildcard patterns may match multiple path segments with /:
         * "/begin/(.*)/end" will match both "/begin/middle/end" and "/begin/1/2/end".
         */
        class RegexMatcher : public MatcherBase
        {
        public:
            RegexMatcher(const std::string &pattern) : regex_(pattern) {}

            bool match(Request &request) const override;

        private:
            std::regex regex_;
        };

        ssize_t write_headers(Stream &strm, const Headers &headers);

    } // namespace detail

    inline void default_socket_options(socket_t sock)
    {
        int yes = 1;
        setsockopt(sock, SOL_SOCKET, SO_REUSEPORT,
                   reinterpret_cast<const void *>(&yes), sizeof(yes));
    }

    // http的服务端
    class Server
    {
    public:
        // 定义一个处理HTTP请求的函数
        using Handler = std::function<void(const Request &, Response)>;

        // 当处理HTTP请求时，如果发生了异常，这个函数会被调用来处理异常情况
        using ExceptionHandler =
            std::function<void(const Request &, Response &, std::exception_ptr ep)>;

        enum class HandlerResponse
        {
            Handled,   // Handled 表示请求已经被处理，服务器应该生成响应。
            Unhandled, // Unhandled 表示请求没有被处理，服务器不应该生成响应
        };

        // 返回一个状态，指示请求是否已经被处理。
        using HandlerWithResponse =
            std::function<HandlerResponse(const Request &, Response &)>;

        // 用于从请求中读取内容
        using HandlerWithContentReader = std::function<void(
            const Request &, Response &, const ContentReader &content_reader)>;

        // 指示服务器是否应该发送100-continue响应，通常在发送大文件时使用
        using Expect100ContinueHandler =
            std::function<int(const Request &, Response &)>;

        Server();

        // 服务器的析构函数，也是虚函数，这意味着它可以被继承并可以在子类中覆盖。（用户扩展）
        virtual ~Server();
        // 检查服务器是否有效（用户扩展）
        virtual bool is_valid() const;

        // 路由处理函数
        Server &Get(const std::string &pattern, Handler handler);
        Server &Post(const std::string &pattern, Handler handler);
        Server &Post(const std::string &pattern, HandlerWithContentReader handler);
        Server &Put(const std::string &pattern, Handler handler);
        Server &Put(const std::string &pattern, HandlerWithContentReader handler);
        Server &Patch(const std::string &pattern, Handler handler);
        Server &Patch(const std::string &pattern, HandlerWithContentReader handler);
        Server &Delete(const std::string &pattern, Handler handler);
        Server &Delete(const std::string &pattern, HandlerWithContentReader handler);
        Server &Options(const std::string &pattern, Handler handler);

        // 设置服务器根目录 ， mount_point是挂载点 例如：/static/hello.html
        // 这里的mount_point是服务器的挂载点
        bool set_base_dir(const std::string &dir,
                          const std::string &mount_point = std::string());

        // 将一个特定的目录映射到一个挂载点
        // 负责设置与该挂载点关联的HTTP头信息。
        // Headers：安全、缓存、认证
        bool set_mount_point(const std::string &mount_point, const std::string &dir,
                             Headers Headers = Headers());

        // 移除一个挂载点
        bool remove_mount_point(const std::string &mount_point);

        // 设置文件扩展名和MIME类型之间的映射关系
        Server &set_file_extension_and_mimetype_mapping(const std::string &ext,
                                                        const std::string &mime);

        // 设置默认的mimetype，没有映射时使用
        Server &set_default_file_mimetype(const std::string &mime);

        // 设置处理文件请求的处理程序
        Server &set_file_request_handler(Handler handler);

        // 允许返回一个响应
        Server &set_error_handler(HandlerWithResponse handler);

        // 只允许让handler处理
        Server &set_error_handler(Handler handler);

        // 异常情况时（如内存不足或非法操作），将调用这个处理程序。
        Server &set_exception_handler(ExceptionHandler handler);

        // 设置预路由处理程序 过滤请求或修改请求路由。
        Server &set_pre_routing_handler(HandlerWithResponse handler);

        // 设置后路由处理程序。在处理请求之后，服务器将调用这个处理程序。
        // 这可以用于对响应进行最后的修改或添加额外的日志记录。
        Server &set_post_routing_handler(Handler handler);

        // 设置Expect: 100-continue处理程序。
        // 当客户端发送一个请求头包含Expect: 100-continue时，
        // 服务器将调用这个处理程序来决定是否继续处理请求。
        Server &set_expect_100_continue_handler(Expect100ContinueHandler handler);

        Server &set_logger(Logger logger);

        // 设置地址家族
        Server &set_address_family(int family);

        // 使得TCP发送数据时不等待完整的窗口大小，从而加快数据传输
        Server &set_tcp_nodelay(bool on);

        // 允许开发者设置一系列的套接字选项
        Server &set_socket_options(SocketOptions socket_options);

        // 允许开发者为所有响应设置默认的头信息
        Server &set_default_headers(Headers headers);

        // 允许开发者指定一个函数，用于在响应发送之前写入头信息。
        // 只能修改它引用的函数或lambda表达式。
        // const function&  和 function const &
        Server &
        set_header_writer(std::function<ssize_t(Stream &, Headers &)> const &writer);

        // 控制服务器在关闭之前应该维持多少次空闲的HTTP/1.1连接。
        Server &set_keep_alive_max_count(size_t count);

        // 控制服务器在关闭之前应该等待多长时间以确认连接是活跃的。
        Server &set_keep_alive_timeout(time_t sec);

        // 允许开发者设置服务器等待客户端数据的时间。
        Server &set_read_timeout(time_t sec, time_t usec = 0);

        // 设置服务器的读取超时和写入超时
        template <class Rep, class Period>
        Server &set_read_timeout(const std::chrono::duration<Rep, Period> &duration);

        Server &set_write_timeout(time_t sec, time_t usec = 0);

        template <class Rep, class Period>
        Server &set_write_timeout(const std::chrono::duration<Rep, Period> &duration);

        // 设置服务器在多长时间内没有活动时要执行的任务，例如关闭连接
        Server &set_idle_interval(time_t sec, time_t usec = 0);

        template <class Rep, class Period>
        Server &set_idle_interval(const std::chrono::duration<Rep, Period> &duration);

        // 服务器能够接受的最大数据负载长度。
        Server &set_payload_max_length(size_t length);

        // ocket_flags 通常用于控制套接字的阻塞模式、重用地址等。
        bool bind_to_port(const std::string &host, int port, int socket_flags = 0);

        int bind_to_any_port(const std::string &host, int socket_flags = 0);

        // 开始监听传入的连接请求。
        bool listen_after_bind();

        // 直接绑定并开始监听指定 host 和 port 上的连接请求。
        bool listen(const std::string &host, int port, int socket_flags = 0);

        bool is_running() const;

        // 等待服务器完成初始化
        void wait_until_ready() const;

        // 终止服务器
        void stop();

        // 异步任务队列
        std::function<TaskQueue *(void)> new_task_queue;

    protected:
        // 处理传入的网络请求
        bool process_request(Stream &strm, bool close_connection,
                             bool &connection_closed,
                             const std::function<void(Request &)> &setup_request);

        std::atomic<socket_t> svr_sock_{INVALID_SOCKET}; // 存储服务器套接字
        size_t keep_alive_max_count_ = CPPHTTPLIB_KEEPALIVE_MAX_COUNT;
        time_t keep_alive_timeout_sec_ = CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND;
        time_t read_timeout_sec_ = CPPHTTPLIB_READ_TIMEOUT_SECOND;
        time_t read_timeout_usec_ = CPPHTTPLIB_READ_TIMEOUT_USECOND;
        time_t write_timeout_sec_ = CPPHTTPLIB_WRITE_TIMEOUT_SECOND;
        time_t write_timeout_usec_ = CPPHTTPLIB_WRITE_TIMEOUT_USECOND;
        time_t idle_interval_sec_ = CPPHTTPLIB_IDLE_INTERVAL_SECOND;
        time_t idle_interval_usec_ = CPPHTTPLIB_IDLE_INTERVAL_USECOND;
        size_t payload_max_length_ = CPPHTTPLIB_PAYLOAD_MAX_LENGTH;

    private:
        // detail::MatcherBase 的实例用来实现具体的匹配逻辑
        using Handlers =
            std::vector<std::pair<std::unique_ptr<detail::MatcherBase>, Handler>>;

        // 路由 和 内容读取 分离
        // 可以单独修改路由规则而不用更改内容处理逻辑
        // 实现模块化设计
        using HandlersForContentReader =
            std::vector<std::pair<std::unique_ptr<detail::MatcherBase>,
                                  HandlerWithContentReader>>;

        // 创建匹配器
        static std::unique_ptr<detail::MatcherBase> make_matcher(
            const std::string &pattern);

        // 创建一个监听客户端连接的套接字 （服务器套接字）
        socket_t create_server_socket(const std::string &host, int port,
                                      int socket_flags,
                                      SocketOptions socket_options) const;

        // 绑定套接字
        int bind_internal(const std::string &host, int port, int socket_flags);

        // 监听套接字
        bool listen_internal();

        // 服务器将根据请求的URL和其他信息来决定如何处理请求，并生成相应的响应。
        bool routing(Request &req, Response &res, Stream &strm);

        bool handle_file_request(const Request &req, Response &res,
                                 bool head = false);

        // 通用处理请求
        bool dispatch_request(Request &req, Response &res,
                              const Handlers &handlers) const;

        bool dispatch_request_for_content_reader(
            Request &req, Response &res, ContentReader content_reader,
            const HandlersForContentReader &handlers) const;

        // 解析http请求行
        bool parse_request_line(const char *s, Request &req) const;

        // 根据请求中的范围头部Range来处理内容
        void apply_ranges(const Request &req, Response &res,
                          std::string &content_type, std::string &boundary) const;

        // 将http响应写入流
        bool write_response(Stream &strm, bool close_connection, const Request &req,
                            Response &res);
        // 包括内容
        bool write_response_with_content(Stream &strm, bool close_connection,
                                         const Request &req, Response &res);

        // 生成响应的主体部分
        bool write_response_core(Stream &strm, bool close_connection,
                                 const Request &req, Response &res,
                                 bool need_apply_ranges);

        //
        bool write_content_with_provider(Stream &strm, const Request &req,
                                         Response &res, const std::string &boundary,
                                         const std::string &content_type);

        // 从流中读取请求内容，对于Post和上传文件操作必要
        bool read_content(Stream &strm, Request &req, Response &res);

        // 多部分表单数据的场景
        bool
        read_content_with_content_receiver(Stream &strm, Request &req, Response &res,
                                           ContentReceiver receiver,
                                           MultipartContentHeader multipart_header,
                                           ContentReceiver multipart_receiver);

        bool read_content_core(Stream &strm, Request &req, Response &res,
                               ContentReceiver receiver,
                               MultipartContentHeader multipart_header,
                               ContentReceiver multipart_receiver) const;
        // 这段代码在一个cpp实现的http库里的server类里，起到什么作用

        virtual bool process_and_close_socket(socket_t sock);

        std::atomic<bool> is_running_{false};
        std::atomic<bool> done_{false};

        struct MountPointEntry
        {
            std::string mount_point;
            std::string base_dir;
            Headers headers;
        };
        std::vector<MountPointEntry> base_dirs_;
        std::map<std::string, std::string> file_extension_and_mimetype_map_;
        std::string default_file_mimetype_ = "application/octet-stream";
        Handler file_request_handler_;

        Handlers get_handlers_;
        Handlers post_handlers_;
        HandlersForContentReader post_handlers_for_content_reader_;
        Handlers put_handlers_;
        HandlersForContentReader put_handlers_for_content_reader_;
        Handlers patch_handlers_;
        HandlersForContentReader patch_handlers_for_content_reader_;
        Handlers delete_handlers_;
        HandlersForContentReader delete_handlers_for_content_reader_;
        Handlers options_handlers_;

        HandlerWithResponse error_handler_;
        ExceptionHandler exception_handler_;
        HandlerWithResponse pre_routing_handler_;
        Handler post_routing_handler_;
        Expect100ContinueHandler expect_100_continue_handler_;

        Logger logger_;

        int address_family_ = AF_UNSPEC;
        bool tcp_nodelay_ = CPPHTTPLIB_TCP_NODELAY;
        SocketOptions socket_options_ = default_socket_options;

        Headers default_headers_;
        std::function<ssize_t(Stream &, Headers &)> header_writer_ =
            detail::write_headers;
    };

} // namespace httplib